package com.lx.entity;

import com.lx.util.LX;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XmlNode {
    private Node node;
    public XmlNode(Node node){
        this.node = node;
    }

    //说明: 是节点
    /** @author ylx 2022/6/15 0015 22:26 */
    private boolean isNode(){
        NodeList childNodes = this.node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node item = childNodes.item(i);
            if (!"#text".equals(item.getNodeName())){
                return true;
            }
        }
        return false;
    }
    //说明: 获取字符串类型
    /** @author ylx 2022/6/15 0015 21:27 */
    public String getString(){
        if (isNode()){
            StringBuilder sb = new StringBuilder();
            NodeList childNodes = this.node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node item = childNodes.item(i);
                if (!"#text".equals(item.getNodeName())){
                    sb.append(nodetoString(item));
                }
            }
            return sb.toString();
        }else{
            return node.getTextContent();
        }
    }
    public int getInt(){
        if (isNode()){
            throw new ClassCastException("该节点不是int类型:"+nodetoString(node));
        }else{
            return Integer.parseInt(node.getTextContent());
        }
    }
    public long getLong(){
        if (isNode()){
            throw new ClassCastException("该节点不是long类型:"+nodetoString(node));
        }else{
            return Long.parseLong(node.getTextContent());
        }
    }
    public BigDecimal getBigDecimal(){
        if (isNode()){
            throw new ClassCastException("该节点不是数字类型:"+nodetoString(node));
        }else{
            return LX.getBigDecimal(node.getTextContent());
        }
    }
    public Map<String , XmlNode> getMap(){
        if (!isNode()){
            throw new ClassCastException("该节点不是Map类型:"+nodetoString(node));
        }else{
            Map<String , XmlNode> map = new HashMap<>();
            NodeList childNodes = this.node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node item = childNodes.item(i);
                if (!"#text".equals(item.getNodeName())){
                    map.put(item.getNodeName() , new XmlNode(item));
                }
            }
            return map;
        }
    }
    public Map<String , String> getStringMap(){
        if (!isNode()){
            throw new ClassCastException("该节点不是Map类型:"+nodetoString(node));
        }else{
            Map<String , String> map = new HashMap<>();
            NodeList childNodes = this.node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node item = childNodes.item(i);
                if (!"#text".equals(item.getNodeName())){
                    map.put(item.getNodeName() , new XmlNode(item).getString());
                }
            }
            return map;
        }
    }
    public List<XmlNode> getList(){
        if (!isNode()){
            throw new ClassCastException("该节点不是List类型:"+nodetoString(node));
        }else{
            List<XmlNode> map = new ArrayList<>();
            NodeList childNodes = this.node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node item = childNodes.item(i);
                if (!"#text".equals(item.getNodeName())){
                    map.add(new XmlNode(item));
                }
            }
            return map;
        }
    }
    public List<Map<String,String>> getStringMapList(){
        if (!isNode()){
            throw new ClassCastException("该节点不是List类型:"+nodetoString(node));
        }else{
            List<Map<String,String>> map = new ArrayList<>();
            NodeList childNodes = this.node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node item = childNodes.item(i);
                if (!"#text".equals(item.getNodeName())){
                    map.add(new XmlNode(item).getStringMap());
                }
            }
            return map;
        }
    }

    //说明: node 转 xml字符串使用
    /** @author ylx 2022/6/15 0015 21:20 */
    private static Transformer transformer;

    private static synchronized Transformer getTransformer() throws TransformerConfigurationException {
        if (transformer != null){
            return transformer;
        }else{
            transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            return transformer;
        }
    }
    //说明: node 转 xml字符串使用
    /** @author ylx 2022/6/15 0015 21:20 */
    public static String nodetoString(Node node) {
        try {
            StringWriter sw = new StringWriter();
            getTransformer().transform(new DOMSource(node), new StreamResult(sw));
            return sw.toString();
        } catch (TransformerException te) {
            throw new RuntimeException(te.getMessage());
        }
    }

    @Override
    public String toString() {
        return getString();
    }
}
